﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using QS.Drawables;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;
using QS.Logic.Objects;
using DPSF;
using GameStateManagement;

namespace QS.Renderer
{
    class QSpaceShipRenderer : QAbstractRenderer
    {
        private Model model;
        private EngineParticleSystem mcParticleSystem;

        public override void LoadContent(GraphicsDevice graphicsDevice, ContentManager contentManager)
        {
            model = contentManager.Load<Model>("Feisar_Ship");

            mcParticleSystem = new EngineParticleSystem();
            mcParticleSystem.AutoInitialize(graphicsDevice, contentManager, null);
        }

        public override void Draw(GraphicsDevice device, QCamera camera, SpriteBatch spriteBatch, IDrawableObject drawableObject)
        {
            QPhysicsObject Object = (QPhysicsObject)drawableObject;
            Matrix[] transforms = new Matrix[model.Bones.Count];

            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();
                    effect.View = camera.ViewMatrix;
                    effect.World = Matrix.CreateRotationY(MathHelper.ToRadians(180f)) * Matrix.CreateRotationX(MathHelper.ToRadians(90f)) * Matrix.CreateScale(0.005f) * Object.Orientation * Matrix.CreateTranslation(Object.Position);
                    effect.Projection = camera.ProjectionMatrix;
                }
                mesh.Draw();
            }

            mcParticleSystem.SpaceShip = (QSpaceShip)drawableObject;
            mcParticleSystem.Update((float)1);
            mcParticleSystem.Emitters[0].Enabled = ((QSpaceShip)drawableObject).EgnineIsOn;
            mcParticleSystem.Emitters[1].Enabled = ((QSpaceShip)drawableObject).EgnineIsOn;
            mcParticleSystem.SetWorldViewProjectionMatrices(Matrix.Identity, camera.ViewMatrix, camera.ProjectionMatrix);
            mcParticleSystem.SetCameraPosition(camera.Position);
            mcParticleSystem.Draw();
        }
    }

    class EngineParticleSystem : DefaultTexturedQuadParticleSystem
    {
        public EngineParticleSystem()
            : base(GameStateManagementGame.Instance)
        {
        }

        private Vector3 LEFT_ENGINE_REL_POSTION = new Vector3( -0.1f,0.1f, 0.9f);
        private Vector3 RIGHT_ENGINE_REL_POSTION = new Vector3( 0.1f, 0.1f, 0.9f);

        public QSpaceShip SpaceShip
        {
            set;
            get;
        }

        public override void AutoInitialize(GraphicsDevice cGraphicsDevice, ContentManager cContentManager, SpriteBatch cSpriteBatch)
        {
            InitializeTexturedQuadParticleSystem(cGraphicsDevice, cContentManager, 1000, 50000, UpdateVertexProperties, "fire");
            Name = "Default Textured Quad Particle System Template";
            LoadParticleSystem();
        }

        public void LoadParticleSystem()
        {
            ParticleInitializationFunction = InitializeParticleUsingInitialProperties;

            InitialProperties.LifetimeMin = 2.0f;
            InitialProperties.LifetimeMax = 2.0f;
            InitialProperties.PositionMin = Vector3.Zero;
            InitialProperties.PositionMax = Vector3.Zero;
            InitialProperties.VelocityMin = new Vector3(0, 0.1f, 0);
            InitialProperties.VelocityMax = new Vector3(0, 0.4f, 0);
            InitialProperties.RotationMin = new Vector3(0, 0, 0);
            InitialProperties.RotationMax = new Vector3(0, 0, MathHelper.Pi);
            InitialProperties.RotationalVelocityMin = new Vector3(0, 0, -MathHelper.Pi);
            InitialProperties.RotationalVelocityMax = new Vector3(0, 0, MathHelper.Pi);
            InitialProperties.StartWidthMin = 0.1f;
            InitialProperties.StartWidthMax = 0.40f;
            InitialProperties.StartHeightMin = 0.10f;
            InitialProperties.StartHeightMax = 0.40f;
            InitialProperties.EndWidthMin = 0.10f;
            InitialProperties.EndWidthMax = 0.10f;
            InitialProperties.EndHeightMin = 0.10f;
            InitialProperties.EndHeightMax = 0.10f;
            InitialProperties.StartColorMin = Color.Black;
            InitialProperties.StartColorMax = Color.White;
            InitialProperties.EndColorMin = Color.Black;
            InitialProperties.EndColorMax = Color.White;

            ParticleEvents.RemoveAllEvents();
            ParticleSystemEvents.RemoveAllEvents();

            ParticleEvents.AddEveryTimeEvent(UpdateParticlePositionUsingVelocity);
            ParticleEvents.AddEveryTimeEvent(UpdateParticleRotationUsingRotationalVelocity);
            ParticleEvents.AddEveryTimeEvent(UpdateParticleWidthAndHeightUsingLerp);
            ParticleEvents.AddEveryTimeEvent(UpdateParticleColorUsingLerp);

            ParticleEvents.AddEveryTimeEvent(UpdateParticleTransparencyToFadeOutUsingLerp, 100);
            ParticleEvents.AddEveryTimeEvent(UpdateParticleToFaceTheCamera, 200);
            ParticleSystemEvents.AddEveryTimeEvent(UpdateParticleSystemFunctionExample, 300);

            ParticleSystemEvents.LifetimeData.EndOfLifeOption = CParticleSystemEvents.EParticleSystemEndOfLifeOptions.Repeat;
            ParticleSystemEvents.LifetimeData.Lifetime = 1.0f;
            ParticleSystemEvents.AddTimedEvent(0.0f, UpdateParticleSystemEmitParticlesAutomaticallyOn);


            Emitter.ParticlesPerSecond = 50;
            Emitter.PositionData.Position = new Vector3(0, 0, 0);
            ParticleEmitter test = new ParticleEmitter();
            test.CopyFrom(Emitter);
            Emitters.Add(test);
        }

        protected void UpdateParticleSystemFunctionExample(float fElapsedTimeInSeconds)
        {
            Emitters[0].PositionData.Position = SpaceShip.Position + Vector3.Transform(LEFT_ENGINE_REL_POSTION, SpaceShip.Orientation);
            Emitters[0].OrientationData.Up = SpaceShip.Orientation.Up;
            Emitters[0].OrientationData.Right = SpaceShip.Orientation.Right;
            Emitters[0].OrientationData.Normal = SpaceShip.Orientation.Up;
            Emitters[1].PositionData.Position = SpaceShip.Position + Vector3.Transform(RIGHT_ENGINE_REL_POSTION, SpaceShip.Orientation);
            Emitters[1].OrientationData.Up = SpaceShip.Orientation.Up;
            Emitters[1].OrientationData.Right = SpaceShip.Orientation.Right;
            Emitters[1].OrientationData.Normal = SpaceShip.Orientation.Up;
        }
    }
}
